#include "stdafx.h"

/* Constructor */
Wnd::Wnd()
	{ 
		isWindowCreated = false;
		pWndController = new WndController(); }

/* Destructor
		Release Resources */
Wnd::~Wnd()
	{ delete pWndController;}

/* Check if the WindowClass is Registered, and registered it when needed.
Then Create Window.*/
void Wnd::MyCreateWindow(LPCTSTR WndText, DWORD dwStyle, 
					int x,  int y ,  int nWidth,  int nHeight,
					HWND hWndParent,  HMENU hMenu,  HINSTANCE hInstance, LPVOID lpParam)
{
	if (!isWndClassRegistered())
	{
		MyRegisterClass(Application::hInst);	// register
		setWndClassRegistered();				// change the flag
	}
	hWnd = ::CreateWindow(getWndClassName(), WndText, 
		dwStyle , x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
}

/***************************************
 * The Core WndProc
 ***/
LRESULT CALLBACK Wnd::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if (!isWindowCreated)
	{
		isWindowCreated = true;
		SendMessage(hWnd, WM_CREATE, 0,0);
		return 0;
	}
	BOOL isCommand = FALSE;
	int wmId, wmEvent;
	if (message == WM_COMMAND)
	{
		isCommand = TRUE;
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
	}
	MsgMappingTable& MappingTbl = pWndController->GetMsgMappingTable();

	// Dispatch WM_COMMAND and treat every Command as a single message
	int messageToFind = isCommand ? wmId : message;

	MSGPROCFUNC pProcFunc = MappingTbl.Find(messageToFind);
	if (pProcFunc != 0)
	{
		return pProcFunc(hWnd, wParam, lParam);
	}

	return ::DefWindowProc(hWnd, message, wParam, lParam);
}

//-----------------------Controller------------------------

/***************************************
 * Basic Constructor
 * Maintaining common message mapping
 ***/
WndController::WndController()
{
	enum {MAPPING_COUNT = 1};

	MsgMappingItem Item[MAPPING_COUNT] = 
	{
		MsgMappingItem(WM_DESTROY, &WndController::OnWndDestroy)
	};

	// Append Message Mapping
	for (int i =0 ; i< MAPPING_COUNT ; i++)
	{
		MappingTable.Append(Item[i]);
	}
}

/* WM_DESTORY */
LRESULT CALLBACK WndController::OnWndDestroy(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	::PostQuitMessage(0);
	return 0;
}

